﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QThread>

class MySessionCB : public Glacier2::SessionCallback {
public:
    MySessionCB(){
    }

    // 通过 SessionCallback 继承
    virtual void createdCommunicator(const Glacier2::SessionHelperPtr & session) override
    {
        qDebug()<<("[log]: createdCommunicator\n");
    }
    virtual void connected(const Glacier2::SessionHelperPtr & session) override
    {
        qDebug()<<("[log]: connected\n");
    }
    virtual void disconnected(const Glacier2::SessionHelperPtr & session) override
    {
        qDebug()<<("[log]: disconnected\n");
    }
    virtual void connectFailed(const Glacier2::SessionHelperPtr & session, const Ice::Exception & ex) override
    {
        qDebug()<<("[log]: connectFailed\n");

    }
};
typedef IceUtil::Handle<MySessionCB> MySessionCBPtr;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    init();
}

MainWindow::~MainWindow()
{
    slot_disconn();
    delete ui;
}

void MainWindow::init()
{
    ui->widget->setEnabled(false);

    pr_DlgLogin = new DlgLogin();
    connect(ui->action_login,SIGNAL(triggered(bool)),this,SLOT(slot_login()));
    connect(pr_DlgLogin,SIGNAL(sig_loginInfo(QString,QString,QString)),this,SLOT(slot_loginInfo(QString,QString,QString)));
    pr_DlgLogin->hide();

    pr_DlgRobotList = new DlgRobotList();
    connect(pr_DlgRobotList,SIGNAL(sig_conn(QString)),this,SLOT(slot_conn(QString)));
    connect(pr_DlgRobotList,SIGNAL(sig_update()),this,SLOT(slot_updateRobotList()));
    pr_DlgRobotList->hide();

    QThread *myThread = new QThread;
    pr_SendMsg = new TMSendMsg();
    pr_SendMsg->moveToThread(myThread);
    connect(this,SIGNAL(sig_sendMsg(QString,QString,QString,NetWorkRobot::UserMangerPrx*)),pr_SendMsg,SLOT(slot_sendMsg(QString,QString,QString,NetWorkRobot::UserMangerPrx*)));
    myThread->start();

    pr_RTMPCtrl = new TMRTMPCtrl;
    connect(this,SIGNAL(sig_getVideoLive(QString,QLabel*)),pr_RTMPCtrl,SLOT(slot_getVideoLive(QString,QLabel*)));
    connect(this,SIGNAL(sig_startAudioLive(QString)),pr_RTMPCtrl,SLOT(slot_startAudioLive(QString)));
    connect(this,SIGNAL(sig_stopVideoLive()),pr_RTMPCtrl,SLOT(slot_stopVideoLive()));
    connect(this,SIGNAL(sig_stopAudioLive()),pr_RTMPCtrl,SLOT(slot_stopAudioLive()));

    connect(ui->action_conn,SIGNAL(triggered(bool)),this,SLOT(slot_showRobotList()));
    connect(ui->action_disconn,SIGNAL(triggered(bool)),this,SLOT(slot_disconn()));



}


void MainWindow::slot_loginInfo(QString m_ip,QString m_name,QString m_pwd)
{
    m_strName = m_name;

    Ice::InitializationData iniData;
    iniData.properties = Ice::createProperties();
    iniData.properties->setProperty(QString("Ice.Default.Router").toUtf8().toStdString(), QString("Glacier2/router:tcp -p 8989 -h %1 -t 2000\r\n").arg(m_ip).toUtf8().toStdString());
    //iniData.properties->setProperty("Ice.Retry.Intervals","-1");

    MySessionCBPtr cbSession = new MySessionCB();
    Glacier2::SessionFactoryHelperPtr _factory;
    Glacier2::SessionHelperPtr _session;
    _factory = new Glacier2::SessionFactoryHelper(iniData, cbSession);
    QString strName = QString("user:%1").arg(m_name);
    _session = _factory->connect(strName.toUtf8().toStdString(), m_pwd.toUtf8().toStdString());


//    Ice::CommunicatorPtr ice = Ice::initialize(iniData);
//    QString strName = QString("user:%1").arg(m_name);
//    Ice::RouterPrx defaultRouter = ice->getDefaultRouter();
//    Glacier2::RouterPrx router = Glacier2::RouterPrx::checkedCast(defaultRouter);
//    Glacier2::SessionPrx session;
//    try{
//        session = router->createSession(strName.toUtf8().toStdString(), m_pwd.toUtf8().toStdString()); //创建基于密码方式的session
//    }catch(Ice::Exception& e){
//        QMessageBox::warning(this, "ERROR", e.what(), QMessageBox::Yes);
//        qDebug()<<"Error:"<<e.what();
//        return;
//    }
    for(int i = 0;i < 100;i++){
        QCoreApplication::processEvents();
        QThread::msleep(5);
    }

    try
    {
        //m_prxUser = NetWorkRobot::UserMangerPrx::uncheckedCast(ice->stringToProxy("UserManger"));
        m_prxUser = NetWorkRobot::UserMangerPrx::uncheckedCast(_session->communicator()->stringToProxy("UserManger"));
//        m_prxUser->ice_ping();
        //m_prxUser->ice_timeout(1000);
        getRobotList();
        pr_DlgLogin->hide();
        pr_DlgRobotList->show();
    }catch(Ice::Exception& e){
        QMessageBox::warning(this, "ERROR", e.what(), QMessageBox::Yes);
        qDebug()<<"Error:"<<e.what();
        return;
    }

}

void MainWindow::slot_updateRobotList()
{
    Ice::StringSeq strlist;
    m_prxUser->robotList(m_strName.toUtf8().toStdString(),strlist);
    pr_DlgRobotList->updateTableWidget(strlist);
}


void MainWindow::getRobotList()
{
    try
    {
        Ice::StringSeq strlist;
        m_prxUser->robotList(m_strName.toUtf8().toStdString(),strlist);
        pr_DlgRobotList->updateTableWidget(strlist);

    }catch(Ice::Exception& e){
        qDebug()<<"Error:"<<e.what();
        return;
    }
}

bool MainWindow::sendMsg(QString strMsg)
{
    emit sig_sendMsg(m_strName,m_strMac,strMsg,&m_prxUser);

    return true;
}

void MainWindow::slot_login()
{
    pr_DlgLogin->show();
}

void MainWindow::slot_conn(QString mac)
{
    try
    {

        m_strMac = mac;
        bool state = m_prxUser->connRobot(m_strName.toUtf8().toStdString(),mac.toUtf8().toStdString());
        if(state){
            pr_DlgRobotList->hide();
            ui->widget->setEnabled(true);
            m_connIP = "rtmp://192.168.102.11/live/robot";

            QString m_iP = m_connIP.mid(7,m_connIP.size()-18);
            qDebug()<<"m_iP"<<m_iP;
            Ice::InitializationData iniData1;
            iniData1.properties = Ice::createProperties();
            iniData1.properties->setProperty(QString("Ice.Default.Router").toUtf8().toStdString(), QString("Glacier2/router:tcp -p 8989 -h %1 -t 2000\r\n").arg(m_iP).toUtf8().toStdString());

            MySessionCBPtr cbSession = new MySessionCB();
            Glacier2::SessionFactoryHelperPtr _factory;

            _factory = new Glacier2::SessionFactoryHelper(iniData1, cbSession);
            m_session = _factory->connect("aa", "bb");

            for(int i = 0;i < 100;i++){
                QCoreApplication::processEvents();
                QThread::msleep(5);
            }

            try
            {
                m_prxPub = Robot::PubPrx::checkedCast(m_session->communicator()->stringToProxy("Pub"));
                m_prxLive = Robot::LivePrx::checkedCast(m_session->communicator()->stringToProxy("Live"));
            }catch(Ice::Exception& e){
                qDebug()<<"Error:"<<e.what();
                return;
            }

            emit sig_getVideoLive(m_connIP,ui->label);
        }else{
            QMessageBox::warning(this, "ERROR", "connect failed!", QMessageBox::Yes);
        }
    }catch(Ice::Exception& e){
        QMessageBox::warning(this, "ERROR", "connect failed!", QMessageBox::Yes);
        qDebug()<<"Error:"<<e.what();
        return;
    }
}

void MainWindow::slot_showRobotList()
{
    getRobotList();
    pr_DlgRobotList->show();
}

void MainWindow::slot_disconn()
{
    try
    {
        qDebug()<<m_prxUser->disConnRobot(m_strName.toUtf8().toStdString(),m_strMac.toUtf8().toStdString());
        ui->widget->setEnabled(false);
    }catch(Ice::Exception& e){
        qDebug()<<"Error:"<<e.what();
        return;
    }
}

void MainWindow::on_pushButton_send_clicked()
{    
    QString str = ui->lineEdit_2->text();
    QString strTTs = QString("{\"type\":\"media\",\"data\":{\"tts\":\"%1\"}}").arg(str);
    sendMsg(strTTs);
}


void MainWindow::on_btn_py_start_clicked()
{
    int nAction = ui->comboBox_action->currentIndex();
    QString strAction = QString("./Scripts/%1.py").arg(ui->comboBox_action->itemText(nAction));
    QString strScript = QString("{\"type\":\"script\",\"data\":{\"path\":\"%1\"}}").arg(strAction);
    sendMsg(strScript);
}

void MainWindow::on_btn_py_stop_clicked()
{
    QString strScript = QString("{\"type\":\"script\",\"data\":{\"play_stop\":true}}");
    sendMsg(strScript);
}

void MainWindow::setHeadData(int nFlag, int nAngle)
{
    if(nFlag == 0)
    {
        m_nHeadUD += nAngle;
        if(m_nHeadUD>10 )
        {
            m_nHeadUD = 10;
        }
        if( m_nHeadUD<-19)
        {
            m_nHeadUD = -19;
        }
    }
    else if(nFlag == 1)
    {
        m_nHeadLR += nAngle;
        if(m_nHeadLR>59 )
        {
            m_nHeadLR = 59;
        }
        if( m_nHeadLR<-59)
        {
            m_nHeadLR = -59;
        }
    }
    else
    {
        m_nHeadLR = 0;
        m_nHeadUD = 0;
    }
}

void MainWindow::controlHead(int nFlag, int nAngle, int nSpeed)
{
    setHeadData(nFlag,nAngle);
    {
        if(nFlag == 0)
        {
            QString strMotor = QString("{\"type\":\"motor\",\"data\":{\"head_ud\":[%1,%2]}}").arg(nAngle).arg(nSpeed);
            sendMsg(strMotor);
        }
        else if(nFlag == 1)
        {
            QString strMotor = QString("{\"type\":\"motor\",\"data\":{\"head_lr\":[%1,%2]}}").arg(nAngle).arg(nSpeed);
            sendMsg(strMotor);
        }
        else
        {
            QString strMotor = QString("{\"type\":\"motor\",\"data\":{\"head_ud\":[%1,%2]}}").arg(nAngle).arg(nSpeed);
            sendMsg(strMotor);
            strMotor = QString("{\"type\":\"motor\",\"data\":{\"head_lr\":[%1,%2]}}").arg(nAngle).arg(nSpeed);
            sendMsg(strMotor);
        }

    }
}

void MainWindow::on_btn_head_up_clicked()
{
    controlHead(0,2,1);
}

void MainWindow::on_btn_head_left_clicked()
{
    controlHead(1,-5,1);
}

void MainWindow::on_btn_head_right_clicked()
{
    controlHead(1,5,1);
}

void MainWindow::on_btn_head_down_clicked()
{
    controlHead(0,-2,1);
}


void MainWindow::on_pushButton_head_reset_clicked()
{
    controlHead(-1,0,1);
}

void MainWindow::setFace(const QModelIndex &faceIndex)
{
    if(faceIndex.isValid())
    {
        int nIndex = faceIndex.row();
        int nSendIndex = -1;

        switch (nIndex) {
        case 0:
            nSendIndex = 5;
            break;
        case 1:
            nSendIndex = 11;
            break;
        case 2:
            nSendIndex = 23;
            break;
        case 3:
            nSendIndex = 24;
            break;
        case 4:
            nSendIndex = 29;
            break;
        case 5:
            nSendIndex = 30;
            break;
        case 6:
            nSendIndex = 34;
            break;
        case 7:
            nSendIndex = 38;
            break;
        case 8:
            nSendIndex = 44;
            break;
        case 9:
            nSendIndex = 47;
            break;
        case 10:
            nSendIndex = 0;
            break;
        case 11:
            nSendIndex = 6;
            break;
        case 12:
            nSendIndex = 19;
            break;
        case 13:
            nSendIndex = 31;
            break;
        case 14:
            nSendIndex = 49;
            break;
        default:
            break;
        }
        QString strMotor = QString("{\"type\":\"led\",\"data\":{\"head_eye\":[0,%1]}}").arg(nSendIndex);
        sendMsg(strMotor);
    }
}

void MainWindow::on_list_face_doubleClicked(const QModelIndex &index)
{
    setFace(index);
}

void MainWindow::on_Btn_talk_clicked()
{
    qDebug()<<"----"<<ui->Btn_talk->text();
    if(ui->Btn_talk->text() == QStringLiteral("开启通话")){
        ui->Btn_talk->setText(QStringLiteral("关闭通话"));
        emit sig_startAudioLive(m_connIP);
        m_prxLive->RemoteRecvStart();
    }else{
        ui->Btn_talk->setText(QStringLiteral("开启通话"));
        emit sig_stopAudioLive();
        m_prxLive->RemoteRecvStop();
    }
}


QString strSubMsg;
class PubCenterI :virtual public Robot::Pub
{
    // PubCenter interface
public:
    void Notify(const std::string &category, const std::string &msg, const Ice::Current &)
    {
        qDebug()<<"Notify:"<<category.c_str()<<msg.c_str();
        strSubMsg = QString("Notify:%1").arg(QString::fromUtf8(msg.c_str()));
    }
};
IceStorm::TopicPrx topic;
void MainWindow::on_Btn_pub_clicked()
{
    try
    {
        Ice::ObjectPrx obj = m_session->communicator()->stringToProxy("PubCenter/TopicManager"); // 修改这里
        //        qDebug()<<obj<<m_icePtr;
        m_topicManager = IceStorm::TopicManagerPrx::checkedCast(obj);
        qDebug()<<m_topicManager->ice_toString().c_str();
        Ice::ObjectAdapterPtr adapter = m_session->communicator()->createObjectAdapterWithEndpoints("MonitorAdapter", "tcp");
        qDebug()<<adapter->getName().c_str();
        Robot::PubPtr monitor = new PubCenterI;
        m_prxSub = adapter->addWithUUID(monitor)->ice_oneway();
        adapter->activate();

        if(topic){
            return;
        }
        topic = m_topicManager->retrieve("Notify");
        //        m_prxPub->Notify("pub","nihao");

    }catch(Ice::Exception& e)
    {
        qDebug()<<"Error:"<<e.what();
    }
}

void MainWindow::on_Btn_sub_clicked()
{

    try
    {
        IceStorm::QoS qos;
        topic->subscribeAndGetPublisher(qos, m_prxSub);

    }
    catch (const IceStorm::NoSuchTopic&)
    {
        qDebug() << "No such topic!";

    }
}

void MainWindow::on_Btn_stop_clicked()
{
    try
    {
        topic->unsubscribe(m_prxSub);

    }
    catch (const IceStorm::NoSuchTopic&)
    {
        qDebug() << "No such topic!";

    }
}

void MainWindow::on_Btn_get_clicked()
{
    ui->textEdit->append(strSubMsg);
}
